package com.zhentao.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhentao.pojo.Menu;
import com.zhentao.pojo.Role;
import com.zhentao.pojo.RoleMenu;
import com.zhentao.service.impl.MenuServiceImpl;
import com.zhentao.service.impl.RoleMenuServiceImpl;
import com.zhentao.service.impl.RoleServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 角色管理控制器
 * @author 杨旭朋
 * @date 2025/1/1
 */
@RequestMapping("/manpower/role")
@RestController
public class RoleController {

    @Autowired
    private RoleServiceImpl roleService;

    @Autowired
    private RoleMenuServiceImpl roleMenuService;

    @Autowired
    private MenuServiceImpl menuService;

    /**
     * 分页查询角色列表
     */
    @PostMapping("list")
    public Page<Role> getRoleList(@RequestBody RoleQueryVO queryVO) {
        Page<Role> page = new Page<>(queryVO.getPageNum(), queryVO.getPageSize());

        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        if (queryVO.getName() != null && !queryVO.getName().trim().isEmpty()) {
            queryWrapper.like("name", queryVO.getName());
        }
        if (queryVO.getCode() != null && !queryVO.getCode().trim().isEmpty()) {
            queryWrapper.like("code", queryVO.getCode());
        }
        queryWrapper.orderByDesc("create_time");

        return roleService.page(page, queryWrapper);
    }

    /**
     * 添加角色
     */
    @PostMapping("add")
    public String addRole(@RequestBody Role role) {
        // 检查角色名称是否已存在
        Role existRole = roleService.getOne(Wrappers.<Role>lambdaQuery()
                .eq(Role::getName, role.getName()));
        if (existRole != null) {
            return "角色名称已存在";
        }

        // 检查角色编码是否已存在
        if (role.getCode() != null && !role.getCode().trim().isEmpty()) {
            existRole = roleService.getOne(Wrappers.<Role>lambdaQuery()
                    .eq(Role::getCode, role.getCode()));
            if (existRole != null) {
                return "角色编码已存在";
            }
        }

        role.setCreateTime(new Date());
        role.setUpdateTime(new Date());

        boolean result = roleService.save(role);
        return result ? "添加成功" : "添加失败";
    }

    /**
     * 更新角色
     */
    @PostMapping("update")
    public String updateRole(@RequestBody Role role) {
        // 检查角色名称是否已存在（排除当前角色）
        Role existRole = roleService.getOne(Wrappers.<Role>lambdaQuery()
                .eq(Role::getName, role.getName())
                .ne(Role::getId, role.getId()));
        if (existRole != null) {
            return "角色名称已存在";
        }

        // 检查角色编码是否已存在（排除当前角色）
        if (role.getCode() != null && !role.getCode().trim().isEmpty()) {
            existRole = roleService.getOne(Wrappers.<Role>lambdaQuery()
                    .eq(Role::getCode, role.getCode())
                    .ne(Role::getId, role.getId()));
            if (existRole != null) {
                return "角色编码已存在";
            }
        }

        role.setUpdateTime(new Date());
        boolean result = roleService.updateById(role);
        return result ? "更新成功" : "更新失败";
    }

    /**
     * 删除角色
     */
    @PostMapping("delete")
    public String deleteRole(@RequestParam("id") Long id) {
        // 检查是否有用户关联此角色
        // TODO: 这里需要检查用户角色关联表

        boolean result = roleService.removeById(id);
        if (result) {
            // 删除角色菜单关联
            roleMenuService.remove(Wrappers.<RoleMenu>lambdaQuery()
                    .eq(RoleMenu::getRoleId, id));
            return "删除成功";
        }
        return "删除失败";
    }

    /**
     * 根据ID获取角色信息
     */
    @PostMapping("getById")
    public Role getRoleById(@RequestParam("id") Long id) {
        return roleService.getById(id);
    }

    /**
     * 获取所有角色（用于下拉选择）
     */
    @PostMapping("getAll")
    public List<Role> getAllRoles() {
        return roleService.list(Wrappers.<Role>lambdaQuery()
                .orderByAsc(Role::getName));
    }

    /**
     * 获取角色的菜单权限
     */
    @PostMapping("getRoleMenus")
    public List<Menu> getRoleMenus(@RequestParam("roleId") Long roleId) {
        // 获取角色关联的菜单ID列表
        List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.<RoleMenu>lambdaQuery()
                .eq(RoleMenu::getRoleId, roleId));

        List<Long> menuIds = new ArrayList<>();
        for (RoleMenu roleMenu : roleMenus) {
            menuIds.add(roleMenu.getMenuId());
        }

        if (menuIds.isEmpty()) {
            return new ArrayList<>();
        }

        // 获取菜单信息
        return menuService.list(Wrappers.<Menu>lambdaQuery()
                .in(Menu::getId, menuIds)
                .orderByAsc(Menu::getSort));
    }

    /**
     * 设置角色的菜单权限
     */
    @PostMapping("setRoleMenus")
    public String setRoleMenus(@RequestBody RoleMenuVO roleMenuVO) {
        Long roleId = roleMenuVO.getRoleId();
        List<Long> menuIds = roleMenuVO.getMenuIds();

        // 先删除原有的角色菜单关联
        roleMenuService.remove(Wrappers.<RoleMenu>lambdaQuery()
                .eq(RoleMenu::getRoleId, roleId));

        // 添加新的角色菜单关联
        if (menuIds != null && !menuIds.isEmpty()) {
            List<RoleMenu> roleMenus = new ArrayList<>();
            for (Long menuId : menuIds) {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(menuId);
                roleMenus.add(roleMenu);
            }
            roleMenuService.saveBatch(roleMenus);
        }

        return "权限设置成功";
    }

    /**
     * 获取所有菜单（用于权限设置）
     */
    @PostMapping("getAllMenus")
    public List<Menu> getAllMenus() {
        return menuService.list(Wrappers.<Menu>lambdaQuery()
                .orderByAsc(Menu::getSort));
    }

    /**
     * 角色查询VO
     */
    public static class RoleQueryVO {
        private Integer pageNum = 1;
        private Integer pageSize = 10;
        private String name;
        private String code;

        // getters and setters
        public Integer getPageNum() { return pageNum; }
        public void setPageNum(Integer pageNum) { this.pageNum = pageNum; }
        public Integer getPageSize() { return pageSize; }
        public void setPageSize(Integer pageSize) { this.pageSize = pageSize; }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getCode() { return code; }
        public void setCode(String code) { this.code = code; }
    }

    /**
     * 角色菜单VO
     */
    public static class RoleMenuVO {
        private Long roleId;
        private List<Long> menuIds;

        // getters and setters
        public Long getRoleId() { return roleId; }
        public void setRoleId(Long roleId) { this.roleId = roleId; }
        public List<Long> getMenuIds() { return menuIds; }
        public void setMenuIds(List<Long> menuIds) { this.menuIds = menuIds; }
    }
}
